using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Text;

namespace DotConferenceSql
{
    /// <summary>
    /// Generic INNER INTO clause element
    /// </summary>
    public class InsertIntoQueryElement : QueryElementBase
    {
        private List<QueryFieldValue> Fields = new List<QueryFieldValue>();

        private string m_table;
        /// <summary>
        /// Gets or sets the affected table.
        /// </summary>
        /// <value>The table.</value>
        public string Table
        {
            get
            {
                return m_table;
            }
            set
            {
                m_table = value;
            }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="InsertIntoQueryElement"/> class.
        /// </summary>
        public InsertIntoQueryElement()
            : base()
        {
            Type = QueryElementType.InsertIntoClause;
        }

        /// <summary>
        /// Adds the field with the specified value
        /// </summary>
        /// <param name="field">The field.</param>
        /// <param name="value">The value.</param>
        public void Add(string field, object value)
        {
            QueryFieldValue newField = new QueryFieldValue();
            newField.field = field;
            newField.value = value;

            Fields.Add(newField);

            // Add SQL parameter too
            Parameters.Add( new SqlParameter(newField.ParamId, value) );
        }

        /// <summary>
        /// Adds the identity.
        /// </summary>
        /// <param name="field">The field.</param>
        public void AddIdentity(string field)
        {
            QueryFieldValue newField = new QueryFieldValue();
            newField.field = field;
            newField.value = "IDENTITY";
            Fields.Add(newField);
        }

        /// <summary>
        /// Generate the part of the query for this element.
        /// </summary>
        /// <returns>generated SQL fragment</returns>
        public override string BuildTextQuery()
        {
            if ( String.IsNullOrEmpty(Table) )
            {
                throw new ArgumentException("The InsertIntoQueryElement does not have a table name");
            }

            if (Fields.Count == 0)
            {
                throw new ArgumentException("The InsertIntoQueryElement does not have any fields");
            }

            // CompositeQueryElement already insert the INSERT INTO clause
            StringBuilder insertQuery = new StringBuilder();
            insertQuery.Append(Table);

            // List fields in the query
            insertQuery.Append("(");
            List<string> fields = new List<string>();
            List<string> parameters = new List<string>();
            foreach(QueryFieldValue field in Fields)
            {
                fields.Add(field.field);
                if (field.value.ToString().CompareTo("IDENTITY") == 0)
                {
                    parameters.Add("SCOPE_IDENTITY()");
                }
                else
                {
                    parameters.Add(field.ParamId);
                }
            }
            insertQuery.Append(String.Join(",", fields.ToArray()));
            insertQuery.Append(")");

            // List parameters
            insertQuery.Append(" VALUES(");
            insertQuery.Append(String.Join(",", parameters.ToArray()));
            insertQuery.Append(")");

            return insertQuery.ToString();
        }
    }
}